#ifndef _H_C_TCP_SOCKET_H_
#define _H_C_TCP_SOCKET_H_

#include "../typedefine.h"
#include "ENetErrorCode.h"
#include "../coroutine.h"
#include <memory>

namespace TB
{
	class CNetService;
	class CTcpSocketImpl;

	class CTcpSocket
	{
		NON_COPYABLE(CTcpSocket)
		NON_MOVEABLE(CTcpSocket)

	private:
		friend class CTcpAcceptorImpl;
		CTcpSocket(int nSocketFD);
	public:
		CTcpSocket();
		~CTcpSocket();
		const std::weak_ptr<CNetService>& GetNetService() const;
		bool Init(const std::weak_ptr<CNetService>& poNetService);
		ENetErrorCode Bind(UINT32 dwIp, UINT16 wPort);
		STask<ENetErrorCode> Connect(UINT32 dwIp, UINT16 wPort, UINT64 qwTimeoutMilliSeconds); //主机字节序
		STask<ENetErrorCode> Send(const std::pair<UINT8*, UINT32>& sBuffer);
		STask<ENetErrorCode> Send(const std::pair<UINT8*, UINT32>& sBuffer1, const std::pair<UINT8*, UINT32>& sBuffer2);
		STask<ENetErrorCode> Send(const std::pair<UINT8*, UINT32>& sBuffer1, const std::pair<UINT8*, UINT32>& sBuffer2, const std::pair<UINT8*, UINT32>& sBuffer3);
		STask<ENetErrorCode> Send(const std::pair<UINT8*, UINT32>* psBuffers, UINT32 dwCount);
		STask<std::pair<ENetErrorCode, UINT32>> Recv(const std::pair<UINT8*, UINT32>& sBuffer);
		STask<std::pair<ENetErrorCode, UINT32>> RecvSome(const std::pair<UINT8*, UINT32>& sBuffer);
		void Close();
		bool IsClosed() const;
		bool IsConnecting() const;
		bool IsConnected() const;
		bool GetLocalIpPort(std::pair<UINT32, UINT16>& roIpPort) const;
		bool GetRemoteIpPort(std::pair<UINT32, UINT16>& roIpPort) const;
		bool SetNoDelay(bool bNoDelay = true);
		bool SetSendBuffer(UINT32 dwSize);
		bool SetRecvBuffer(UINT32 dwSize);

	private:
		std::shared_ptr<CTcpSocketImpl> m_poImpl;
	};
}

#endif